/**
 *
 */
package com.angel.common.providers.base;

import java.io.Serializable;

import com.angel.common.providers.exceptions.CannotGetExcludeValueForObjectException;
import com.angel.common.providers.managers.FieldRangeValueAnnotationManager;
import com.angel.dao.generic.interfaces.GenericDAO;

/**
 * @author William
 *
 */
public class RangeValueProvider<T extends Object, H extends Comparable<Object>> extends ObjectProvider<T>{

	private static final long serialVersionUID = 6339341444496906085L;
	private FieldRangeValueAnnotationManager rangeValueAnnotationManager = new FieldRangeValueAnnotationManager();
	private Comparable<H> maximun;
	private Comparable<H> minimun;

	public RangeValueProvider(GenericDAO<T, Serializable> genericDAO, Class<T> classObject, Comparable<H> maximun, Comparable<H> minimun){
		super(genericDAO, classObject);
		this.maximun = maximun;
		this.minimun = minimun;
	}

	public RangeValueProvider(Class<T> classObject, Comparable<H> maximun, Comparable<H> minimun){
		super(classObject);
		this.maximun = maximun;
		this.minimun = minimun;
	}

	/**
	 * @return the maximun
	 */
	protected Comparable<H> getMaximun() {
		return maximun;
	}

	/**
	 * @param maximun the maximun to set
	 */
	protected void setMaximun(Comparable<H> maximun) {
		this.maximun = maximun;
	}

	/**
	 * @return the minimun
	 */
	protected Comparable<H> getMinimun() {
		return minimun;
	}

	/**
	 * @param minimun the minimun to set
	 */
	protected void setMinimun(Comparable<H> minimun) {
		this.minimun = minimun;
	}

	public boolean isValidRangeValueFor(Object object){
		boolean isOutOfLimit = false;
//		Collection<?> values = super.getValues();
//		for(Object o: values){
//			Object minimunObject = rangeValueAnnotationManager.findRangeValueFor(RangeValueType.MINIMUN, o);
//			Object maximunObject = rangeValueAnnotationManager.findRangeValueFor(RangeValueType.MAXIMUN, o);
//			if(!isOutOfLimit){
//				isOutOfLimit = CompareHelper.isOverlappedRangeBetweenComparableObjects(minimunObject, maximunObject, minimun, maximun);
//			}
//		}
		return isOutOfLimit;
	}

	@Override
	public boolean addObject(String name, T object){
		boolean addedObject = false;
		boolean canFindRangeValue = rangeValueAnnotationManager.canFindRangeValueFor(object.getClass());
		if(canFindRangeValue){
			addedObject = this.addObjectWith(name, object);
		} else {
			throw new CannotGetExcludeValueForObjectException("It could NOT get exclude objet for object to adds with field or method exclude value annotation.");
		}
		return addedObject;
	}

	@Override
	public boolean addObject(T object){
		boolean canFindRangeValue = rangeValueAnnotationManager.canFindRangeValueFor(object.getClass());
		boolean addedObject = false;
		if(canFindRangeValue){
			boolean areValidLimits = this.isValidRangeValueFor(object);
			if(areValidLimits){
				addedObject = super.addObject(object);
			}
		} else {
			throw new CannotGetExcludeValueForObjectException("It could NOT get exclude objet for object to adds with field or method exclude value annotation.");
		}
		return addedObject;
	}

	private boolean addObjectWith(String name, T object){
		boolean addedObject = false;
		boolean isOutOfLimit = this.isValidRangeValueFor(object);
		if(isOutOfLimit){
			addedObject = super.addObject(name, object);
		}
		return addedObject;
	}
}
